<script setup lang="ts">
import { useCategoryStore } from "@/stores/categoryStore";
import { onBeforeRouteUpdate } from "vue-router";
import omitBy from "lodash/omitBy";
import type { GoodsRequestParams } from "@/types/Goods";
import { transform } from "lodash";
import XtxSkeleton from "../../../components/XtxSkeleton.vue";

// 获取用于存储分类状态的 store 对象
const categoryStore = useCategoryStore();
// 获取路由信息对象
const route = useRoute();
// 获取二级分类筛选条件
const { subCategoryFilters } = storeToRefs(categoryStore);
// 获取请求二级分类筛选方法
const { getSubCategoryFilters } = categoryStore;
// 发送请求 获取当前二级分类下的筛选条件
getSubCategoryFilters(route.params.sub as string);

// 路由组件什么时候会发生挂载和卸载的行为
// 当路由规则发生变化时  比如从首页跳转到一级分类页  比如从一级分类跳转到二级分类
// 比如从首页跳转到二级分类页 / => /category /category => /category/sub / => /category/sub

// 为什么要清楚的知道以上的挂载卸载行为
// 因为 setup 中的代码只有在挂载的时候执行一次

// 也就是说从一个一级分类跳转到另一个一级分类  路由规则没有发生变化  所以一级分类路由组件中
// 的 setup 中的代码不会执行  /category/1 => /category/2

// 监听路由变化
onBeforeRouteUpdate((to) => {
  // 发送请求 获取目标二级分类下的筛选条件
  getSubCategoryFilters(to.params.sub as string);
  // 重置用户的筛选条件
  selectedFilters.value = {};
});

// 先收集用户选择的筛选条件
// {brandId: "1", "规则": "170克"}
// {brandId: "1", "规则": undefined, "尺码": "120cm"}
// 转换筛选条件的数据格式
// {brandId: "1", attrs: [{groupName: "规则", proprtyName: "170克"}]}

// 触发自定义事件
const emit = defineEmits<{ (e: "onChanged", params: FilterParams): void }>();

// 服务器端要求的请求参数的数据格式
type FilterParams = Partial<Pick<GoodsRequestParams, "brandId" | "attrs">>;

// 定义收集筛选条件的对象的数据类型
interface SelectedFilters {
  brandId: string;
  [groupName: string]: string;
}
// 存储用户选择的筛选条件
const selectedFilters = ref<Partial<SelectedFilters>>({});
// 当筛选条件发生变化的时候
function onSelectedFiltersChanged(filters: Partial<SelectedFilters>) {
  // 更新筛选条件
  selectedFilters.value = { ...selectedFilters.value, ...filters };
  // 临时存储
  const temp = omitBy(selectedFilters.value, (value) => value === undefined);
  // console.log(selectedFilters.value);

  //
  const params = transform(
    temp,
    function (result: FilterParams, value, key) {
      if (key === "brandId") {
        result[key] = value;
      } else {
        if (typeof result["attrs"] === "undefined") result["attrs"] = [];
        result["attrs"].push({ groupName: key, propertyName: value! });
      }
    },
    {}
  );

  // 通过自定义事件的方式把用户选择的筛选条件传递到父组件
  emit("onChanged", params);
}
</script>
<template>
  <div class="sub-filter" v-if="subCategoryFilters.status === 'loading'">
    <XtxSkeleton class="item" width="800px" height="25px" />
    <XtxSkeleton class="item" width="800px" height="25px" />
    <XtxSkeleton class="item" width="600px" height="25px" />
    <XtxSkeleton class="item" width="600px" height="25px" />
    <XtxSkeleton class="item" width="600px" height="25px" />
  </div>
  <div class="sub-filter" v-else>
    <div class="item">
      <div class="head">品牌：</div>
      <div class="body">
        <a
          :class="{ active: selectedFilters.brandId === undefined }"
          href="javascript:"
          @click="onSelectedFiltersChanged({ brandId: undefined })"
          >全部</a
        >
        <a
          href="javascript:"
          :class="{ active: selectedFilters.brandId === brand.id }"
          v-for="brand in subCategoryFilters.result[route.params.sub as string]?.brands"
          :key="brand.id"
          @click="onSelectedFiltersChanged({ brandId: brand.id })"
          >{{ brand.name }}</a
        >
      </div>
    </div>
    <!-- 渲染其他的 -->
    <div
      class="item"
      v-for="salePropertie in subCategoryFilters.result[route.params.sub as string]?.saleProperties"
      :key="salePropertie.id"
    >
      <div class="head">{{ salePropertie.name }}：</div>
      <div class="body">
        <a
          :class="{ active: selectedFilters[salePropertie.name] === undefined }"
          href="javascript:"
          @click="onSelectedFiltersChanged({ [salePropertie.name]: undefined })"
          >全部</a
        >
        <a
          :class="{
            active: selectedFilters[salePropertie.name] === property.name,
          }"
          href="javascript:"
          v-for="property in salePropertie.properties"
          :key="property.id"
          @click="
            onSelectedFiltersChanged({ [salePropertie.name]: property.name })
          "
          >{{ property.name }}</a
        >
      </div>
    </div>
  </div>
</template>

<style scoped lang="less">
.xtx-skeleton {
  margin: 10px 0;
}
.sub-filter {
  background: #fff;
  padding: 25px;
  .item {
    display: flex;
    line-height: 40px;
    .head {
      width: 80px;
      color: #999;
    }
    .body {
      flex: 1;
      a {
        margin-right: 36px;
        transition: all 0.3s;
        display: inline-block;
        &.active,
        &:hover {
          color: @xtxColor;
        }
      }
    }
  }
}
</style>
